all files / fc-er/ controller.js

60.76% Statements 223/367
47.54% Branches 135/284
67.21% Functions 41/61
63.99% Lines 215/336
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761       1318×                                                                                                                   1517×   1517×   1517× 1517× 1517× 1517× 1517× 1517×                     12408×         1520×         1527×         12391×         1520×                                     71492×                   1365×                   12390×                   1365×                   6937×                 1520× 1520×     1520× 1520×         28986× 28986×         12391×         13755× 13755× 12390×     1365× 1365×       1365×       1365× 1365×     1365× 1365×         1365×         22049× 22049×   22049× 1357×           1357× 1357×   1357×     20692× 1369×     20692× 6937×           6937× 6937×   6937×     6936×     13755× 13755× 1365×             1365× 1365× 1365× 1365×     12390×         12391×   12391× 12391× 12391×   12391×         12390× 1377× 1377×     12390× 1377× 1377×     12390× 1377× 1377× 1377× 1377×   1377× 1377×           12390× 12390× 12390× 12390×     12390× 12390× 10911× 10911× 10911×           12390× 12389×     12390× 12343× 81×     12262×                             12262×             12262× 12262×                                                                     12390× 12390×         12390×         12262×   12262×   12262× 12261×       12261× 10830×           10830× 10830×     12261×   12261× 12261×       12262×         12262× 12262×           12262×                                                       12262× 12262×   12262×         12391×         12391×   12391×   12390×     12391×   12391× 12391×   12391×         12391×   12391× 12391× 12391×   12391×         12390×   12390×     12390× 10911×     12390×       12390× 12390×   12390× 12261×                                                                                                                                                                                                                                                                                               12390×                          
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
 
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
 
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
function _possibleConstructorReturn(self, call) { Iif (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
 
function _inherits(subClass, superClass) { Iif (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); Eif (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); }
 
Iif (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
 
define(function (require) {
    'use strict';
 
    var URL = require('./URL');
    var config = require('./config');
    var util = require('./util');
    var assert = require('./assert');
    var EventTarget = require('fc-mini-event/EventTarget');
    var Permission = require('./permission').Permission;
    var router = require('./router');
    var canUseDOM = require('./ExecutionEnvironment').canUseDOM;
 
    var removeChildAction = function removeChildAction(controller, container, targetContext) {
        var info = controller.childActionMapping[container.id];
        Eif (!info) {
            return;
        }
 
        controller.childActionMapping[container.id] = undefined;
        if (info.hijack) {
            if (container.removeEventListener) {
                container.removeEventListener('click', info.hijack, false);
            } else {
                container.detachEvent('onclick', info.hijack);
            }
        }
 
        if (info.action) {
            targetContext = targetContext || {
                url: null,
                referrer: info.url,
                container: container.id,
                isChildAction: true
            };
            var eventBus = controller.getEventBus();
            eventBus && eventBus.fire('leaveaction', {
                controller: controller,
                action: info.action,
                to: targetContext
            });
        }
 
        if (typeof info.action.leave === 'function') {
            info.action.leave();
        }
    };
 
    var addChildAction = function addChildAction(controller, container, action, hijack, context) {
        removeChildAction(controller, container, context);
 
        Eif (container.addEventListener) {
            container.addEventListener('click', hijack, false);
        } else {
            container.attachEvent('onclick', hijack);
        }
 
        controller.childActionMapping[container.id] = {
            url: context.url,
            container: container.id,
            action: action,
            hijack: hijack
        };
 
        Eif (action instanceof EventTarget) {
            // 在Action销毁的时候要取消掉
            action.on('leave', function () {
                removeChildAction(controller, container);
            });
        }
    };
 
    var Controller = function (_EventTarget) {
        _inherits(Controller, _EventTarget);
 
        function Controller() {
            _classCallCheck(this, Controller);
 
            var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Controller).call(this));
 
            _this.childActionMapping = {};
            _this.currentURL = null;
            _this.currentAction = null;
            _this.globalActionLoader = null;
            _this.childActionLoaders = {};
            return _this;
        }
 
        _createClass(Controller, [{
            key: 'registerAction',
            value: function registerAction(actionConfigs) {
                var main = require('./main');
                main.registerAction(actionConfigs);
            }
        }, {
            key: 'getDefaultTitle',
            value: function getDefaultTitle() {
                return this.defaultTitle;
            }
        }, {
            key: 'setDefaultTitle',
            value: function setDefaultTitle(title) {
                this.defaultTitle = title;
            }
        }, {
            key: 'setErContext',
            value: function setErContext(erContext) {
                this.erContext = erContext;
            }
        }, {
            key: 'getErContext',
            value: function getErContext() {
                return this.erContext;
            }
        }, {
            key: 'getRouter',
            value: function getRouter() {
                return this.erContext && this.erContext.getRouter();
            }
        }, {
            key: 'setRouter',
            value: function setRouter(router) {
                this.erContext && this.erContext.setRouter(router);
            }
        }, {
            key: 'getLocator',
            value: function getLocator() {
                return this.erContext && this.erContext.getLocator();
            }
        }, {
            key: 'setLocator',
            value: function setLocator(locator) {
                this.erContext && this.erContext.setLocator(locator);
            }
        }, {
            key: 'getEventBus',
            value: function getEventBus() {
                return this.erContext && this.erContext.getEventBus();
            }
        }, {
            key: 'setEventBus',
            value: function setEventBus(eventBus) {
                this.erContext && this.erContext.setEventBus(eventBus);
            }
        }, {
            key: 'getPermissionProvider',
            value: function getPermissionProvider() {
                return this.erContext && this.erContext.getPermissionProvider();
            }
        }, {
            key: 'setPermissionProvider',
            value: function setPermissionProvider(permissionProvider) {
                this.erContext && this.erContext.setPermissionProvider(permissionProvider);
            }
        }, {
            key: 'getMainContainer',
            value: function getMainContainer() {
                return this.mainContainer || config.mainElement;
            }
        }, {
            key: 'setMainContainer',
            value: function setMainContainer(mainContainer) {
                this.mainContainer = mainContainer;
            }
        }, {
            key: 'getNoAuthorityLocation',
            value: function getNoAuthorityLocation() {
                return this.noAuthorityLocation || config.noAuthorityLocation;
            }
        }, {
            key: 'setNoAuthorityLocation',
            value: function setNoAuthorityLocation(noAuthorityLocation) {
                this.noAuthorityLocation = noAuthorityLocation;
            }
        }, {
            key: 'getNotFoundLocation',
            value: function getNotFoundLocation() {
                return this.notFoundLocation || config.notFoundLocation;
            }
        }, {
            key: 'setNotFoundLocation',
            value: function setNotFoundLocation(notFoundLocation) {
                this.notFoundLocation = notFoundLocation;
            }
        }, {
            key: 'start',
            value: function start() {
                Eif (canUseDOM && !this.getDefaultTitle()) {
                    this.setDefaultTitle(config.systemName || global.document.title);
                }
 
                var router = this.getRouter();
                router && router.setBackup(util.bind(this.renderAction, this));
            }
        }, {
            key: 'findActionConfig',
            value: function findActionConfig(actionContext) {
                var main = require('./main');
                return main.findActionConfig(actionContext);
            }
        }, {
            key: 'resolveActionConfig',
            value: function resolveActionConfig(actionConfig, actionContext) {
                return actionConfig;
            }
        }, {
            key: 'checkAuthority',
            value: function checkAuthority(actionConfig, actionContext) {
                var authority = actionConfig.authority;
                if (!authority) {
                    return true;
                }
 
                var permissionProvider = this.getPermissionProvider();
                Iif (!permissionProvider) {
                    return true;
                }
 
                Iif (typeof authority === 'function') {
                    return authority(actionContext, actionConfig, permissionProvider);
                }
 
                Eif (typeof authority === 'string') {
                    authority = authority.split('|');
                }
 
                for (var i = 0; i < authority.length; i++) {
                    Iif (permissionProvider.isAllow(util.trim(authority[i]))) {
                        return true;
                    }
                }
 
                return false;
            }
        }, {
            key: 'findEligibleActionConfig',
            value: function findEligibleActionConfig(actionContext) {
                var actionConfig = this.findActionConfig(actionContext);
                var eventBus = this.getEventBus();
 
                if (actionConfig && actionConfig.movedTo) {
                    eventBus && eventBus.fire('actionmoved', {
                        controller: this,
                        url: actionContext.url,
                        config: actionConfig,
                        movedTo: actionConfig.movedTo
                    });
                    actionContext.originalURL = actionContext.url;
                    actionContext.url = URL.parse(actionConfig.movedTo);
 
                    return this.findEligibleActionConfig(actionContext);
                }
 
                if (actionConfig && actionConfig.childActionOnly && !actionContext.isChildAction) {
                    actionConfig = null;
                }
 
                if (!actionConfig) {
                    eventBus && eventBus.fire('actionnotfound', util.mix({
                        controller: this,
                        failType: 'NotFound',
                        reason: 'Not found'
                    }, actionContext));
 
                    actionContext.originalURL = actionContext.url;
                    actionContext.url = URL.parse(this.getNotFoundLocation());
 
                    if (!this.findActionConfig(actionContext)) {
                        return null;
                    }
 
                    return this.findEligibleActionConfig(actionContext);
                }
 
                var hasAuthority = this.checkAuthority(actionConfig, actionContext);
                if (!hasAuthority) {
                    eventBus && eventBus.fire('permissiondenied', util.mix({
                        controller: this,
                        failType: 'PermissionDenied',
                        reason: 'Permission denied',
                        config: actionConfig
                    }, actionContext));
 
                    var location = actionConfig.noAuthorityLocation || this.getNoAuthorityLocation();
                    actionContext.originalURL = actionContext.url;
                    actionContext.url = URL.parse(location);
                    return this.findEligibleActionConfig(actionContext);
                }
 
                return actionConfig;
            }
        }, {
            key: 'loadAction',
            value: function loadAction(actionContext) {
                var _this2 = this;
 
                var actionConfig = this.findEligibleActionConfig(actionContext);
                actionConfig = this.resolveActionConfig(actionConfig, actionContext);
                var eventBus = this.getEventBus();
 
                if (!actionConfig) {
                    var failed = new Promise(function (resolve, reject) {
                        reject('no action configured for url ' + actionContext.url.getPath());
                    });
 
                    return failed;
                }
 
                if (actionConfig.title) {
                    actionContext.title = actionConfig.title;
                    actionContext.args.title = actionConfig.title;
                }
 
                if (actionConfig.documentTitle) {
                    actionContext.documentTitle = actionConfig.documentTitle;
                    actionContext.args.documentTitle = actionConfig.documentTitle;
                }
 
                if (actionConfig.args) {
                    for (var name in actionConfig.args) {
                        Eif (actionConfig.args.hasOwnProperty(name)) {
                            Eif (!actionContext.args.hasOwnProperty(name)) {
                                actionContext.args[name] = actionConfig.args[name];
                            }
                            Eif (!actionContext.hasOwnProperty(name)) {
                                actionContext[name] = actionConfig.args[name];
                            }
                        }
                    }
                }
 
                var loading = {};
                var loader = new Promise(function (resolve, reject) {
                    loading.resolve = resolve;
                    loading.reject = reject;
                });
 
                var aborted = false;
                loader.abort = function () {
                    Eif (!aborted) {
                        aborted = true;
                        eventBus && eventBus.fire('actionabort', util.mix({
                            controller: _this2
                        }, actionContext));
                    }
                };
 
                if (!actionContext.isChildAction) {
                    this.currentURL = actionContext.url;
                }
 
                var callback = function callback(SpecificAction) {
                    if (aborted) {
                        return;
                    }
 
                    Iif (!SpecificAction) {
                        var reason = 'No action implement for ' + actionConfig.type;
                        var error = util.mix({
                            controller: _this2,
                            failType: 'NoModule',
                            config: actionConfig,
                            reason: reason
                        }, actionContext);
 
                        eventBus && eventBus.fire('actionfail', error);
                        eventBus && eventBus.notifyError(error);
                        loading.reject(reason);
                        return;
                    }
 
                    eventBus && eventBus.fire('actionloaded', {
                        controller: _this2,
                        url: actionContext.url,
                        config: actionConfig,
                        action: SpecificAction
                    });
 
                    Eif (typeof SpecificAction === 'function') {
                        loading.resolve({
                            action: new SpecificAction(),
                            actionContext: actionContext
                        });
                    } else if (typeof SpecificAction.createRuntimeAction === 'function') {
                        var resolveActionInstance = function resolveActionInstance(args) {
                            var action = args.action;
 
                            if (!action) {
                                var _reason = 'Action factory returns non-action';
                                var _error = util.mix({
                                    controller: _this2,
                                    failType: 'InvalidFactory',
                                    config: actionConfig,
                                    reason: _reason,
                                    action: action
                                }, actionContext);
                                eventBus && eventBus.fire('actionfail', _error);
                                eventBus && eventBus.notifyError(_error);
 
                                loading.reject(_reason);
                            } else {
                                loading.resolve({ action: action, actionContext: actionContext });
                            }
                        };
                        var actionFactoryProduct = SpecificAction.createRuntimeAction(actionContext);
                        Promise.resolve(actionFactoryProduct).then(resolveActionInstance);
                    } else {
                        loading.resolve({
                            action: SpecificAction,
                            actionContext: actionContext
                        });
                    }
                };
 
                Eif (typeof actionConfig.type === 'string') {
                    Controller.getRequire()([actionConfig.type], callback);
                } else {
                    callback(actionConfig.type);
                }
 
                return loader;
            }
        }, {
            key: 'enterAction',
            value: function enterAction(action, actionContext) {
                var _this3 = this;
 
                var eventBus = this.getEventBus();
 
                if (!actionContext.isChildAction) {
                    Iif (actionContext.url !== this.currentURL) {
                        return;
                    }
 
                    if (this.currentAction) {
                        eventBus && eventBus.fire('leaveaction', {
                            controller: this,
                            action: this.currentAction,
                            to: util.mix({}, actionContext)
                        });
 
                        Eif (typeof this.currentAction.leave === 'function') {
                            this.currentAction.leave();
                        }
                    }
                    this.currentAction = action;
 
                    Eif (global.document) {
                        global.document.title = actionContext.title || actionContext.documentTitle || this.getDefaultTitle();
                    }
                }
 
                eventBus && eventBus.fire('enteraction', util.mix({
                    controller: this,
                    action: action
                }, actionContext));
 
                var notifyEnterComplete = function notifyEnterComplete() {
                    eventBus && eventBus.fire('enteractioncomplete', util.mix({
                        controller: _this3,
                        action: action
                    }, actionContext));
                };
 
                var notifyEnterFail = function notifyEnterFail(reason) {
                    var message = '';
                    if (!reason) {
                        message = 'Invoke action.enter() causes error';
                    } else if (reason.message) {
                        message = reason.message;
                        if (reason.stack) {
                            message += '\n' + reason.stack;
                        }
                    } else if (JSON && typeof JSON.stringify === 'function') {
                        try {
                            message = JSON.stringify(reason);
                        } catch (parseJSONError) {
                            message = reason;
                        }
                    } else {
                        message = reason;
                    }
 
                    var error = util.mix({
                        failType: 'EnterFail',
                        reason: message
                    }, actionContext);
 
                    eventBus && eventBus.fire('enteractionfail', error);
                    eventBus && eventBus.notifyError(error);
                };
 
                var entering = action.enter(actionContext);
                entering.then(notifyEnterComplete, notifyEnterFail);
 
                return entering;
            }
        }, {
            key: 'forward',
            value: function forward(url, container, options, isChildAction) {
                var actionContext = {
                    url: url,
                    container: container,
                    isChildAction: !!isChildAction
                };
                var eventBus = this.getEventBus();
 
                if (isChildAction) {
                    var referrerInfo = this.childActionMapping[container];
                    actionContext.referrer = referrerInfo ? referrerInfo.url : null;
                } else {
                    actionContext.referrer = this.currentURL;
                }
 
                util.mix(actionContext, options);
 
                actionContext.args = util.mix({}, actionContext);
                util.mix(actionContext.args, url.getQuery());
 
                Iif (!isChildAction && this.rehydratedCurrentURL && this.rehydratedCurrentURL.getPath() === url.getPath()) {
                    actionContext.rehydratedModel = this.rehydratedModel;
                    this.rehydratedCurrentURL = null;
                    this.rehydratedModel = null;
                }
                actionContext.erContext = this.getErContext();
 
                eventBus && eventBus.fire('forwardaction', util.mix({ controller: this }, actionContext));
                var loader = this.loadAction(actionContext);
                assert.has(loader, 'loadAction should always return a Promise');
 
                return loader;
            }
        }, {
            key: 'renderAction',
            value: function renderAction(url) {
                var _this4 = this;
 
                Iif (typeof url === 'string') {
                    url = URL.parse(url);
                }
                if (this.globalActionLoader && typeof this.globalActionLoader.abort === 'function') {
                    this.globalActionLoader.abort();
                }
 
                Iif (this.currentAction && typeof this.currentAction.filterRedirect === 'function' && this.currentAction.filterRedirect(url) === false) {
                    return Promise.reject('Redirect aborted by previous action');
                }
 
                this.globalActionLoader = this.forward(url, this.getMainContainer(), null, false);
                var eventBus = this.getEventBus();
 
                return this.globalActionLoader.then(function (args) {
                    return _this4.enterAction.call(_this4, args.action, args.actionContext);
                }).then(null, function (error) {
                    eventBus && eventBus.notifyError(error);
                    throw error;
                });
            }
        }, {
            key: 'enterChildAction',
            value: function enterChildAction(action, actionContext) {
                this.childActionLoaders[actionContext.container] = null;
 
                var container = void 0;
                Eif (global.document && global.document.getElementById) {
                    container = global.document.getElementById(actionContext.container);
                }
                Iif (!container) {
                    return;
                }
 
                var locator = this.getLocator();
                var currentController = this;
 
                var redirect = function redirect(url, options, extra) {
                    options = options || {};
                    url = locator.resolveURL(url, options);
 
                    if (options.global) {
                        var globalRedirectPerformed = locator.redirect(url, options);
                        if (globalRedirectPerformed && container) {
                            removeChildAction(currentController, container);
                        }
                        return globalRedirectPerformed;
                    }
 
                    var childActionInfo = currentController.childActionMapping[actionContext.container];
                    var changed = url.toString() !== childActionInfo.url.toString();
                    var shouldPerformRedirect = changed || options.force;
                    if (shouldPerformRedirect) {
                        if (options.silent) {
                            childActionInfo.url = url;
                        } else {
                            currentController.renderChildAction(url, childActionInfo.container, extra);
                        }
                    }
 
                    return shouldPerformRedirect;
                };
 
                var isChildActionRedirected = function isChildActionRedirected(e) {
                    // 除低版本IE外,其它浏览器是可以在事件对象上加自定义属性的,IE每次都生成新的事件对象所以保留不了这些属性,
                    // 在这里优先用自定义属性控制,避免对DOM树无意义的遍历,只有在没有属性的时候,才向后兼容至DOM树的遍历
                    if (e.isChildActionRedirected) {
                        return true;
                    }
 
                    var innermostContainer = e.target || e.srcElement;
                    while (innermostContainer) {
                        // 是Action容器的元素肯定符合以下条件:
                        //
                        // - 有个`id`,因为没有`id`不能渲染子Action
                        // - 这个`id`在`childActionMapping`里是有对应的值的
                        if (innermostContainer.id && currentController.childActionMapping[innermostContainer.id]) {
                            break;
                        }
 
                        innermostContainer = innermostContainer.parentNode;
                    }
                    // 如果最接近被点击的链接的Action容器是不是当前的这个容器,就说明在当前容器和链接之间还有一层以上的子Action,
                    // 那么这个子Action肯定会处理掉这个链接的跳转,不需要这里处理了
                    if (innermostContainer.id !== actionContext.container) {
                        e.isChildActionRedirected = true;
                        return true;
                    }
 
                    return false;
                };
 
                // 需要把`container`上的链接点击全部拦截下来,如果是hash跳转,则转到controller上来
                var hijack = function hijack(e) {
                    // 下面两行是以主流浏览器为主,兼容IE的事件属性操作
                    e = e || global.window && global.window.event;
                    var target = e.target || e.srcElement;
 
                    // 担心有人在`<span>`之类的上面放`href`属性,还是判断一下标签
                    if (target.nodeName.toLowerCase() !== 'a') {
                        return;
                    }
 
                    // `<a>`元素也可能没有`href`属性
                    var href = target.getAttribute('href', 2) || '';
                    // 是hash跳转的链接就取消掉默认的跳转行为
                    if (href.charAt(0) !== '#') {
                        return;
                    }
                    // 如果有下面的子Action处理了跳转,那这里就啥也不干了
                    if (isChildActionRedirected(e)) {
                        return;
                    }
 
                    if (e.preventDefault) {
                        e.preventDefault();
                    } else {
                        e.returnValue = false;
                    }
 
                    // 转到`renderChildAction`上
                    var url = href.substring(1);
 
                    // 直接使用专供子Action上的`redirect`方法,
                    // 会自动处理`hijack`的解绑定、URL比对、进入子Action等事,
                    // 为免Action重写`redirect`方法,这里用闭包内的这个
                    var redirectAttributes = (target.getAttribute('data-redirect') || '').split(/[,\s]/);
                    var redirectOptions = {};
                    for (var i = 0; i < redirectAttributes.length; i++) {
                        var redirectAttributeName = util.trim(redirectAttributes[i]);
                        redirectOptions[redirectAttributeName] = true;
                    }
                    redirect(url, redirectOptions);
                };
 
                action.redirect = redirect;
 
                action.reload = function (extra) {
                    this.redirect(actionContext.url, { force: true }, extra);
                };
 
                action.back = function (defaultURL, extra) {
                    var referrer = this.context && this.context.referrer;
                    var url = referrer || defaultURL;
                    this.redirect(url, null, extra);
                };
                addChildAction(this, container, action, hijack, actionContext);
 
                return this.enterAction(action, actionContext);
            }
        }, {
            key: 'renderChildAction',
            value: function renderChildAction(url, container, options) {
                var _this5 = this;
 
                assert.has(container);
 
                Eif (typeof url === 'string') {
                    url = URL.parse(url);
                }
 
                var previousLoader = this.childActionLoaders[container];
                Iif (previousLoader && typeof previousLoader.abort === 'function') {
                    previousLoader.abort();
                }
 
                var actionInfo = this.childActionMapping[container];
                var previousAction = actionInfo && actionInfo.action;
                Iif (previousAction && typeof previousAction.filterRedirect === 'function' && previousAction.filterRedirect(url) === false) {
                    return Promise.reject('Redirect aborted by previous action');
                }
 
                var loader = this.forward(url, container, options, true);
                var events = this.getEventBus();
                var loadingChildAction = loader.then(function (args) {
                    return _this5.enterChildAction.call(_this5, args.action, args.actionContext);
                }).then(null, util.bind(events.notifyError, events));
                // `then`方法会返回一个新的`Promise`,但原来的`loader`上有个`abort`方法,要把这个方法留下来
                loadingChildAction.abort = loader.abort;
                this.childActionLoaders[container] = loadingChildAction;
                return loadingChildAction;
            }
        }, {
            key: 'rehydrate',
            value: function rehydrate(rehydratedState) {
                Iif (rehydratedState && rehydratedState.currentURL) {
                    this.rehydratedCurrentURL = URL.parse(rehydratedState.currentURL);
                    this.rehydratedModel = util.mix({}, rehydratedState.model, { url: this.rehydratedCurrentURL });
                }
            }
        }], [{
            key: 'getRequire',
            value: function getRequire() {
                return Controller.require || require;
            }
        }, {
            key: 'setRequire',
            value: function setRequire(require) {
                Controller.require = require;
            }
        }]);
 
        return Controller;
    }(EventTarget);
 
    var instance = new Controller();
    instance.Controller = Controller;
 
    return instance;
});
//# sourceMappingURL=data:application/json;base64,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Q0FEK0M7QUFFL0MseUJBQUssZUFBTCxHQUF1QixLQUFLLEdBQUwsQ0FBUyxFQUFULEVBQWEsZ0JBQWdCLEtBQWhCLEVBQXVCLEVBQUMsS0FBSyxLQUFLLG9CQUFMLEVBQTFDLENBQXZCLENBRitDO2lCQUFuRDs7Ozt5Q0FNaUI7QUFDakIsdUJBQU8sV0FBVyxPQUFYLElBQXNCLE9BQXRCLENBRFU7Ozs7dUNBSUYsU0FBUztBQUN4QiwyQkFBVyxPQUFYLEdBQXFCLE9BQXJCLENBRHdCOzs7OztNQTFuQlAsYUF6RUg7O0FBd3NCdEIsUUFBSSxXQUFXLElBQUksVUFBSixFQUFYLENBeHNCa0I7QUF5c0J0QixhQUFTLFVBQVQsR0FBc0IsVUFBdEIsQ0F6c0JzQjs7QUEyc0J0QixXQUFPLFFBQVAsQ0Ezc0JzQjtDQUFuQixDQUFQIiwiZmlsZSI6ImNvbnRyb2xsZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpZiAodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykge3ZhciBkZWZpbmUgPSByZXF1aXJlKCdhbWRlZmluZScpKG1vZHVsZSl9XG5cbmRlZmluZShmdW5jdGlvbiAocmVxdWlyZSkge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIGNvbnN0IFVSTCA9IHJlcXVpcmUoJy4vVVJMJyk7XG4gICAgY29uc3QgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTtcbiAgICBjb25zdCB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG4gICAgY29uc3QgYXNzZXJ0ID0gcmVxdWlyZSgnLi9hc3NlcnQnKTtcbiAgICBjb25zdCBFdmVudFRhcmdldCA9IHJlcXVpcmUoJ2ZjLW1pbmktZXZlbnQvRXZlbnRUYXJnZXQnKTtcbiAgICBjb25zdCBQZXJtaXNzaW9uID0gcmVxdWlyZSgnLi9wZXJtaXNzaW9uJykuUGVybWlzc2lvbjtcbiAgICBjb25zdCByb3V0ZXIgPSByZXF1aXJlKCcuL3JvdXRlcicpO1xuICAgIGNvbnN0IGNhblVzZURPTSA9IHJlcXVpcmUoJy4vRXhlY3V0aW9uRW52aXJvbm1lbnQnKS5jYW5Vc2VET007XG5cbiAgICBjb25zdCByZW1vdmVDaGlsZEFjdGlvbiA9IChjb250cm9sbGVyLCBjb250YWluZXIsIHRhcmdldENvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgaW5mbyA9IGNvbnRyb2xsZXIuY2hpbGRBY3Rpb25NYXBwaW5nW2NvbnRhaW5lci5pZF07XG4gICAgICAgIGlmICghaW5mbykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udHJvbGxlci5jaGlsZEFjdGlvbk1hcHBpbmdbY29udGFpbmVyLmlkXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGluZm8uaGlqYWNrKSB7XG4gICAgICAgICAgICBpZiAoY29udGFpbmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICBjb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBpbmZvLmhpamFjaywgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmRldGFjaEV2ZW50KCdvbmNsaWNrJywgaW5mby5oaWphY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluZm8uYWN0aW9uKSB7XG4gICAgICAgICAgICB0YXJnZXRDb250ZXh0ID0gdGFyZ2V0Q29udGV4dCB8fCB7XG4gICAgICAgICAgICAgICAgdXJsOiBudWxsLFxuICAgICAgICAgICAgICAgIHJlZmVycmVyOiBpbmZvLnVybCxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IGNvbnRhaW5lci5pZCxcbiAgICAgICAgICAgICAgICBpc0NoaWxkQWN0aW9uOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZXZlbnRCdXMgPSBjb250cm9sbGVyLmdldEV2ZW50QnVzKCk7XG4gICAgICAgICAgICBldmVudEJ1cyAmJiBldmVudEJ1cy5maXJlKCdsZWF2ZWFjdGlvbicsIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLFxuICAgICAgICAgICAgICAgIGFjdGlvbjogaW5mby5hY3Rpb24sXG4gICAgICAgICAgICAgICAgdG86IHRhcmdldENvbnRleHRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBpbmZvLmFjdGlvbi5sZWF2ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgaW5mby5hY3Rpb24ubGVhdmUoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBhZGRDaGlsZEFjdGlvbiA9IChjb250cm9sbGVyLCBjb250YWluZXIsIGFjdGlvbiwgaGlqYWNrLCBjb250ZXh0KSA9PiB7XG4gICAgICAgIHJlbW92ZUNoaWxkQWN0aW9uKGNvbnRyb2xsZXIsIGNvbnRhaW5lciwgY29udGV4dCk7XG5cbiAgICAgICAgaWYgKGNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoaWphY2ssIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5hdHRhY2hFdmVudCgnb25jbGljaycsIGhpamFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBjb250cm9sbGVyLmNoaWxkQWN0aW9uTWFwcGluZ1tjb250YWluZXIuaWRdID0ge1xuICAgICAgICAgICAgdXJsOiBjb250ZXh0LnVybCxcbiAgICAgICAgICAgIGNvbnRhaW5lcjogY29udGFpbmVyLmlkLFxuICAgICAgICAgICAgYWN0aW9uOiBhY3Rpb24sXG4gICAgICAgICAgICBoaWphY2s6IGhpamFja1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChhY3Rpb24gaW5zdGFuY2VvZiBFdmVudFRhcmdldCkge1xuICAgICAgICAgICAgLy8g5ZyoQWN0aW9u6ZSA5q+B55qE5pe25YCZ6KaB5Y+W5raI5o6JXG4gICAgICAgICAgICBhY3Rpb24ub24oJ2xlYXZlJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlbW92ZUNoaWxkQWN0aW9uKGNvbnRyb2xsZXIsIGNvbnRhaW5lcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBjbGFzcyBDb250cm9sbGVyIGV4dGVuZHMgRXZlbnRUYXJnZXQge1xuICAgICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgICAgIHN1cGVyKCk7XG4gICAgICAgICAgICB0aGlzLmNoaWxkQWN0aW9uTWFwcGluZyA9IHt9O1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50VVJMID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEFjdGlvbiA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmdsb2JhbEFjdGlvbkxvYWRlciA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmNoaWxkQWN0aW9uTG9hZGVycyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmVnaXN0ZXJBY3Rpb24gKGFjdGlvbkNvbmZpZ3MpIHtcbiAgICAgICAgICAgIGNvbnN0IG1haW4gPSByZXF1aXJlKCcuL21haW4nKTtcbiAgICAgICAgICAgIG1haW4ucmVnaXN0ZXJBY3Rpb24oYWN0aW9uQ29uZmlncyk7XG4gICAgICAgIH1cblxuICAgICAgICBnZXREZWZhdWx0VGl0bGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZWZhdWx0VGl0bGU7XG4gICAgICAgIH1cblxuICAgICAgICBzZXREZWZhdWx0VGl0bGUodGl0bGUpIHtcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdFRpdGxlID0gdGl0bGU7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRFckNvbnRleHQoZXJDb250ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLmVyQ29udGV4dCA9IGVyQ29udGV4dDtcbiAgICAgICAgfVxuXG4gICAgICAgIGdldEVyQ29udGV4dCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVyQ29udGV4dDtcbiAgICAgICAgfVxuXG4gICAgICAgIGdldFJvdXRlcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVyQ29udGV4dCAmJiB0aGlzLmVyQ29udGV4dC5nZXRSb3V0ZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldFJvdXRlcihyb3V0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZXJDb250ZXh0ICYmIHRoaXMuZXJDb250ZXh0LnNldFJvdXRlcihyb3V0ZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgZ2V0TG9jYXRvcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVyQ29udGV4dCAmJiB0aGlzLmVyQ29udGV4dC5nZXRMb2NhdG9yKCk7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRMb2NhdG9yKGxvY2F0b3IpIHtcbiAgICAgICAgICAgIHRoaXMuZXJDb250ZXh0ICYmIHRoaXMuZXJDb250ZXh0LnNldExvY2F0b3IobG9jYXRvcik7XG4gICAgICAgIH1cblxuICAgICAgICBnZXRFdmVudEJ1cygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVyQ29udGV4dCAmJiB0aGlzLmVyQ29udGV4dC5nZXRFdmVudEJ1cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0RXZlbnRCdXMoZXZlbnRCdXMpIHtcbiAgICAgICAgICAgIHRoaXMuZXJDb250ZXh0ICYmIHRoaXMuZXJDb250ZXh0LnNldEV2ZW50QnVzKGV2ZW50QnVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGdldFBlcm1pc3Npb25Qcm92aWRlcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVyQ29udGV4dCAmJiB0aGlzLmVyQ29udGV4dC5nZXRQZXJtaXNzaW9uUHJvdmlkZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldFBlcm1pc3Npb25Qcm92aWRlcihwZXJtaXNzaW9uUHJvdmlkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZXJDb250ZXh0ICYmIHRoaXMuZXJDb250ZXh0LnNldFBlcm1pc3Npb25Qcm92aWRlcihwZXJtaXNzaW9uUHJvdmlkZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgZ2V0TWFpbkNvbnRhaW5lcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1haW5Db250YWluZXIgfHwgY29uZmlnLm1haW5FbGVtZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0TWFpbkNvbnRhaW5lcihtYWluQ29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLm1haW5Db250YWluZXIgPSBtYWluQ29udGFpbmVyO1xuICAgICAgICB9XG5cbiAgICAgICAgZ2V0Tm9BdXRob3JpdHlMb2NhdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5vQXV0aG9yaXR5TG9jYXRpb24gfHwgY29uZmlnLm5vQXV0aG9yaXR5TG9jYXRpb247XG4gICAgICAgIH1cblxuICAgICAgICBzZXROb0F1dGhvcml0eUxvY2F0aW9uKG5vQXV0aG9yaXR5TG9jYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMubm9BdXRob3JpdHlMb2NhdGlvbiA9IG5vQXV0aG9yaXR5TG9jYXRpb247XG4gICAgICAgIH1cblxuICAgICAgICBnZXROb3RGb3VuZExvY2F0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubm90Rm91bmRMb2NhdGlvbiB8fCBjb25maWcubm90Rm91bmRMb2NhdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldE5vdEZvdW5kTG9jYXRpb24obm90Rm91bmRMb2NhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5ub3RGb3VuZExvY2F0aW9uID0gbm90Rm91bmRMb2NhdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXJ0KCkge1xuICAgICAgICAgICAgaWYgKGNhblVzZURPTSAmJiAhdGhpcy5nZXREZWZhdWx0VGl0bGUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0RGVmYXVsdFRpdGxlKGNvbmZpZy5zeXN0ZW1OYW1lIHx8IGdsb2JhbC5kb2N1bWVudC50aXRsZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJvdXRlciA9IHRoaXMuZ2V0Um91dGVyKCk7XG4gICAgICAgICAgICByb3V0ZXIgJiYgcm91dGVyLnNldEJhY2t1cCh1dGlsLmJpbmQodGhpcy5yZW5kZXJBY3Rpb24sIHRoaXMpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZpbmRBY3Rpb25Db25maWcgKGFjdGlvbkNvbnRleHQpIHtcbiAgICAgICAgICAgIGNvbnN0IG1haW4gPSByZXF1aXJlKCcuL21haW4nKTtcbiAgICAgICAgICAgIHJldHVybiBtYWluLmZpbmRBY3Rpb25Db25maWcoYWN0aW9uQ29udGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXNvbHZlQWN0aW9uQ29uZmlnKGFjdGlvbkNvbmZpZywgYWN0aW9uQ29udGV4dCkge1xuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbkNvbmZpZztcbiAgICAgICAgfVxuXG4gICAgICAgIGNoZWNrQXV0aG9yaXR5KGFjdGlvbkNvbmZpZywgYWN0aW9uQ29udGV4dCkge1xuICAgICAgICAgICAgbGV0IGF1dGhvcml0eSA9IGFjdGlvbkNvbmZpZy5hdXRob3JpdHk7XG4gICAgICAgICAgICBpZiAoIWF1dGhvcml0eSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBwZXJtaXNzaW9uUHJvdmlkZXIgPSB0aGlzLmdldFBlcm1pc3Npb25Qcm92aWRlcigpO1xuICAgICAgICAgICAgaWYgKCFwZXJtaXNzaW9uUHJvdmlkZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBhdXRob3JpdHkgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXV0aG9yaXR5KGFjdGlvbkNvbnRleHQsIGFjdGlvbkNvbmZpZywgcGVybWlzc2lvblByb3ZpZGVyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBhdXRob3JpdHkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgYXV0aG9yaXR5ID0gYXV0aG9yaXR5LnNwbGl0KCd8Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXV0aG9yaXR5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBlcm1pc3Npb25Qcm92aWRlci5pc0FsbG93KHV0aWwudHJpbShhdXRob3JpdHlbaV0pKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZpbmRFbGlnaWJsZUFjdGlvbkNvbmZpZyhhY3Rpb25Db250ZXh0KSB7XG4gICAgICAgICAgICBsZXQgYWN0aW9uQ29uZmlnID0gdGhpcy5maW5kQWN0aW9uQ29uZmlnKGFjdGlvbkNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgZXZlbnRCdXMgPSB0aGlzLmdldEV2ZW50QnVzKCk7XG5cbiAgICAgICAgICAgIGlmIChhY3Rpb25Db25maWcgJiYgYWN0aW9uQ29uZmlnLm1vdmVkVG8pIHtcbiAgICAgICAgICAgICAgICBldmVudEJ1cyAmJiBldmVudEJ1cy5maXJlKCdhY3Rpb25tb3ZlZCcsIHtcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlcjogdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgdXJsOiBhY3Rpb25Db250ZXh0LnVybCxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnOiBhY3Rpb25Db25maWcsXG4gICAgICAgICAgICAgICAgICAgIG1vdmVkVG86IGFjdGlvbkNvbmZpZy5tb3ZlZFRvXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgYWN0aW9uQ29udGV4dC5vcmlnaW5hbFVSTCA9IGFjdGlvbkNvbnRleHQudXJsO1xuICAgICAgICAgICAgICAgIGFjdGlvbkNvbnRleHQudXJsID0gVVJMLnBhcnNlKGFjdGlvbkNvbmZpZy5tb3ZlZFRvKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbmRFbGlnaWJsZUFjdGlvbkNvbmZpZyhhY3Rpb25Db250ZXh0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFjdGlvbkNvbmZpZyAmJiAoYWN0aW9uQ29uZmlnLmNoaWxkQWN0aW9uT25seSAmJiAhYWN0aW9uQ29udGV4dC5pc0NoaWxkQWN0aW9uKSkge1xuICAgICAgICAgICAgICAgIGFjdGlvbkNvbmZpZyA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghYWN0aW9uQ29uZmlnKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRCdXMgJiYgZXZlbnRCdXMuZmlyZSgnYWN0aW9ubm90Zm91bmQnLCB1dGlsLm1peCh7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXI6IHRoaXMsXG4gICAgICAgICAgICAgICAgICAgIGZhaWxUeXBlOiAnTm90Rm91bmQnLFxuICAgICAgICAgICAgICAgICAgICByZWFzb246ICdOb3QgZm91bmQnXG4gICAgICAgICAgICAgICAgfSwgYWN0aW9uQ29udGV4dCkpO1xuXG4gICAgICAgICAgICAgICAgYWN0aW9uQ29udGV4dC5vcmlnaW5hbFVSTCA9IGFjdGlvbkNvbnRleHQudXJsO1xuICAgICAgICAgICAgICAgIGFjdGlvbkNvbnRleHQudXJsID0gVVJMLnBhcnNlKHRoaXMuZ2V0Tm90Rm91bmRMb2NhdGlvbigpKTtcblxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5maW5kQWN0aW9uQ29uZmlnKGFjdGlvbkNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbmRFbGlnaWJsZUFjdGlvbkNvbmZpZyhhY3Rpb25Db250ZXh0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaGFzQXV0aG9yaXR5ID0gdGhpcy5jaGVja0F1dGhvcml0eShhY3Rpb25Db25maWcsIGFjdGlvbkNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFoYXNBdXRob3JpdHkpIHtcbiAgICAgICAgICAgICAgICBldmVudEJ1cyAmJiBldmVudEJ1cy5maXJlKCdwZXJtaXNzaW9uZGVuaWVkJywgdXRpbC5taXgoe1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyOiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICBmYWlsVHlwZTogJ1Blcm1pc3Npb25EZW5pZWQnLFxuICAgICAgICAgICAgICAgICAgICByZWFzb246ICdQZXJtaXNzaW9uIGRlbmllZCcsXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZzogYWN0aW9uQ29uZmlnXG4gICAgICAgICAgICAgICAgfSwgYWN0aW9uQ29udGV4dCkpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgbG9jYXRpb24gPSBhY3Rpb25Db25maWcubm9BdXRob3JpdHlMb2NhdGlvbiB8fCB0aGlzLmdldE5vQXV0aG9yaXR5TG9jYXRpb24oKTtcbiAgICAgICAgICAgICAgICBhY3Rpb25Db250ZXh0Lm9yaWdpbmFsVVJMID0gYWN0aW9uQ29udGV4dC51cmw7XG4gICAgICAgICAgICAgICAgYWN0aW9uQ29udGV4dC51cmwgPSBVUkwucGFyc2UobG9jYXRpb24pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbmRFbGlnaWJsZUFjdGlvbkNvbmZpZyhhY3Rpb25Db250ZXh0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbkNvbmZpZztcbiAgICAgICAgfVxuXG4gICAgICAgIGxvYWRBY3Rpb24oYWN0aW9uQ29udGV4dCkge1xuICAgICAgICAgICAgbGV0IGFjdGlvbkNvbmZpZyA9IHRoaXMuZmluZEVsaWdpYmxlQWN0aW9uQ29uZmlnKGFjdGlvbkNvbnRleHQpO1xuICAgICAgICAgICAgYWN0aW9uQ29uZmlnID0gdGhpcy5yZXNvbHZlQWN0aW9uQ29uZmlnKGFjdGlvbkNvbmZpZywgYWN0aW9uQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBldmVudEJ1cyA9IHRoaXMuZ2V0RXZlbnRCdXMoKTtcblxuICAgICAgICAgICAgaWYgKCFhY3Rpb25Db25maWcpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmYWlsZWQgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChgbm8gYWN0aW9uIGNvbmZpZ3VyZWQgZm9yIHVybCAke2FjdGlvbkNvbnRleHQudXJsLmdldFBhdGgoKX1gKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBmYWlsZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhY3Rpb25Db25maWcudGl0bGUpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb25Db250ZXh0LnRpdGxlID0gYWN0aW9uQ29uZmlnLnRpdGxlO1xuICAgICAgICAgICAgICAgIGFjdGlvbkNvbnRleHQuYXJncy50aXRsZSA9IGFjdGlvbkNvbmZpZy50aXRsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFjdGlvbkNvbmZpZy5kb2N1bWVudFRpdGxlKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uQ29udGV4dC5kb2N1bWVudFRpdGxlID0gYWN0aW9uQ29uZmlnLmRvY3VtZW50VGl0bGU7XG4gICAgICAgICAgICAgICAgYWN0aW9uQ29udGV4dC5hcmdzLmRvY3VtZW50VGl0bGUgPSBhY3Rpb25Db25maWcuZG9jdW1lbnRUaXRsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFjdGlvbkNvbmZpZy5hcmdzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIGFjdGlvbkNvbmZpZy5hcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb25Db25maWcuYXJncy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhY3Rpb25Db250ZXh0LmFyZ3MuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25Db250ZXh0LmFyZ3NbbmFtZV0gPSBhY3Rpb25Db25maWcuYXJnc1tuYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYWN0aW9uQ29udGV4dC5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkNvbnRleHRbbmFtZV0gPSBhY3Rpb25Db25maWcuYXJnc1tuYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbG9hZGluZyA9IHt9O1xuICAgICAgICAgICAgY29uc3QgbG9hZGVyID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGxvYWRpbmcucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgICAgICAgICAgbG9hZGluZy5yZWplY3QgPSByZWplY3Q7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgbGV0IGFib3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGxvYWRlci5hYm9ydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWFib3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgYWJvcnRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50QnVzICYmIGV2ZW50QnVzLmZpcmUoJ2FjdGlvbmFib3J0JywgdXRpbC5taXgoe1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlcjogdGhpc1xuICAgICAgICAgICAgICAgICAgICB9LCBhY3Rpb25Db250ZXh0KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCFhY3Rpb25Db250ZXh0LmlzQ2hpbGRBY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRVUkwgPSBhY3Rpb25Db250ZXh0LnVybDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSAoU3BlY2lmaWNBY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYWJvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFTcGVjaWZpY0FjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWFzb24gPSBgTm8gYWN0aW9uIGltcGxlbWVudCBmb3IgJHthY3Rpb25Db25maWcudHlwZX1gO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IHV0aWwubWl4KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXI6IHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBmYWlsVHlwZTogJ05vTW9kdWxlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZzogYWN0aW9uQ29uZmlnLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uOiByZWFzb25cbiAgICAgICAgICAgICAgICAgICAgfSwgYWN0aW9uQ29udGV4dCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZXZlbnRCdXMgJiYgZXZlbnRCdXMuZmlyZSgnYWN0aW9uZmFpbCcsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRCdXMgJiYgZXZlbnRCdXMubm90aWZ5RXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICBsb2FkaW5nLnJlamVjdChyZWFzb24pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXZlbnRCdXMgJiYgZXZlbnRCdXMuZmlyZSgnYWN0aW9ubG9hZGVkJywge1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyOiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICB1cmw6IGFjdGlvbkNvbnRleHQudXJsLFxuICAgICAgICAgICAgICAgICAgICBjb25maWc6IGFjdGlvbkNvbmZpZyxcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiBTcGVjaWZpY0FjdGlvblxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBTcGVjaWZpY0FjdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBsb2FkaW5nLnJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiBuZXcgU3BlY2lmaWNBY3Rpb24oKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkNvbnRleHRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBTcGVjaWZpY0FjdGlvbi5jcmVhdGVSdW50aW1lQWN0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVBY3Rpb25JbnN0YW5jZSA9IChhcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7YWN0aW9ufSA9IGFyZ3M7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlYXNvbiA9ICdBY3Rpb24gZmFjdG9yeSByZXR1cm5zIG5vbi1hY3Rpb24nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gdXRpbC5taXgoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyOiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsVHlwZTogJ0ludmFsaWRGYWN0b3J5JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnOiBhY3Rpb25Db25maWcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgYWN0aW9uQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRCdXMgJiYgZXZlbnRCdXMuZmlyZSgnYWN0aW9uZmFpbCcsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudEJ1cyAmJiBldmVudEJ1cy5ub3RpZnlFcnJvcihlcnJvcik7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkaW5nLnJlamVjdChyZWFzb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGluZy5yZXNvbHZlKHthY3Rpb24sIGFjdGlvbkNvbnRleHR9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWN0aW9uRmFjdG9yeVByb2R1Y3QgPSBTcGVjaWZpY0FjdGlvbi5jcmVhdGVSdW50aW1lQWN0aW9uKGFjdGlvbkNvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoYWN0aW9uRmFjdG9yeVByb2R1Y3QpLnRoZW4ocmVzb2x2ZUFjdGlvbkluc3RhbmNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvYWRpbmcucmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IFNwZWNpZmljQWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uQ29udGV4dFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbkNvbmZpZy50eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIENvbnRyb2xsZXIuZ2V0UmVxdWlyZSgpKFthY3Rpb25Db25maWcudHlwZV0sIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGFjdGlvbkNvbmZpZy50eXBlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGxvYWRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGVudGVyQWN0aW9uKGFjdGlvbiwgYWN0aW9uQ29udGV4dCkge1xuICAgICAgICAgICAgY29uc3QgZXZlbnRCdXMgPSB0aGlzLmdldEV2ZW50QnVzKCk7XG5cbiAgICAgICAgICAgIGlmICghYWN0aW9uQ29udGV4dC5pc0NoaWxkQWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFjdGlvbkNvbnRleHQudXJsICE9PSB0aGlzLmN1cnJlbnRVUkwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRBY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRCdXMgJiYgZXZlbnRCdXMuZmlyZSgnbGVhdmVhY3Rpb24nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyOiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiB0aGlzLmN1cnJlbnRBY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICB0bzogdXRpbC5taXgoe30sIGFjdGlvbkNvbnRleHQpXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5jdXJyZW50QWN0aW9uLmxlYXZlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRBY3Rpb24ubGVhdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRBY3Rpb24gPSBhY3Rpb247XG5cbiAgICAgICAgICAgICAgICBpZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGdsb2JhbC5kb2N1bWVudC50aXRsZSA9IGFjdGlvbkNvbnRleHQudGl0bGUgfHwgYWN0aW9uQ29udGV4dC5kb2N1bWVudFRpdGxlIHx8IHRoaXMuZ2V0RGVmYXVsdFRpdGxlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBldmVudEJ1cyAmJiBldmVudEJ1cy5maXJlKCdlbnRlcmFjdGlvbicsIHV0aWwubWl4KHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyOiB0aGlzLFxuICAgICAgICAgICAgICAgIGFjdGlvblxuICAgICAgICAgICAgfSwgYWN0aW9uQ29udGV4dCkpO1xuXG4gICAgICAgICAgICBjb25zdCBub3RpZnlFbnRlckNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50QnVzICYmIGV2ZW50QnVzLmZpcmUoJ2VudGVyYWN0aW9uY29tcGxldGUnLCB1dGlsLm1peCh7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXI6IHRoaXMsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvblxuICAgICAgICAgICAgICAgIH0sIGFjdGlvbkNvbnRleHQpKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IG5vdGlmeUVudGVyRmFpbCA9IChyZWFzb24pID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgbWVzc2FnZSA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICghcmVhc29uKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSAnSW52b2tlIGFjdGlvbi5lbnRlcigpIGNhdXNlcyBlcnJvcic7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlYXNvbi5tZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSByZWFzb24ubWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlYXNvbi5zdGFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSArPSAnXFxuJyArIHJlYXNvbi5zdGFjaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChKU09OICYmIHR5cGVvZiBKU09OLnN0cmluZ2lmeSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEpTT04uc3RyaW5naWZ5KHJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKHBhcnNlSlNPTkVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gcmVhc29uO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gcmVhc29uO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gdXRpbC5taXgoe1xuICAgICAgICAgICAgICAgICAgICBmYWlsVHlwZTogJ0VudGVyRmFpbCcsXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvbjogbWVzc2FnZVxuICAgICAgICAgICAgICAgIH0sIGFjdGlvbkNvbnRleHQpO1xuXG4gICAgICAgICAgICAgICAgZXZlbnRCdXMgJiYgZXZlbnRCdXMuZmlyZSgnZW50ZXJhY3Rpb25mYWlsJywgZXJyb3IpO1xuICAgICAgICAgICAgICAgIGV2ZW50QnVzICYmIGV2ZW50QnVzLm5vdGlmeUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGVudGVyaW5nID0gYWN0aW9uLmVudGVyKGFjdGlvbkNvbnRleHQpO1xuICAgICAgICAgICAgZW50ZXJpbmcudGhlbihub3RpZnlFbnRlckNvbXBsZXRlLCBub3RpZnlFbnRlckZhaWwpO1xuXG4gICAgICAgICAgICByZXR1cm4gZW50ZXJpbmc7XG4gICAgICAgIH1cblxuICAgICAgICBmb3J3YXJkKHVybCwgY29udGFpbmVyLCBvcHRpb25zLCBpc0NoaWxkQWN0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb25Db250ZXh0ID0ge1xuICAgICAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgICAgICBjb250YWluZXIsXG4gICAgICAgICAgICAgICAgaXNDaGlsZEFjdGlvbjogISFpc0NoaWxkQWN0aW9uXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZXZlbnRCdXMgPSB0aGlzLmdldEV2ZW50QnVzKCk7XG5cbiAgICAgICAgICAgIGlmIChpc0NoaWxkQWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmZXJyZXJJbmZvID0gdGhpcy5jaGlsZEFjdGlvbk1hcHBpbmdbY29udGFpbmVyXTtcbiAgICAgICAgICAgICAgICBhY3Rpb25Db250ZXh0LnJlZmVycmVyID0gcmVmZXJyZXJJbmZvID8gcmVmZXJyZXJJbmZvLnVybCA6IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhY3Rpb25Db250ZXh0LnJlZmVycmVyID0gdGhpcy5jdXJyZW50VVJMO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1dGlsLm1peChhY3Rpb25Db250ZXh0LCBvcHRpb25zKTtcblxuICAgICAgICAgICAgYWN0aW9uQ29udGV4dC5hcmdzID0gdXRpbC5taXgoe30sIGFjdGlvbkNvbnRleHQpO1xuICAgICAgICAgICAgdXRpbC5taXgoYWN0aW9uQ29udGV4dC5hcmdzLCB1cmwuZ2V0UXVlcnkoKSk7XG5cbiAgICAgICAgICAgIGlmICghaXNDaGlsZEFjdGlvbiAmJiB0aGlzLnJlaHlkcmF0ZWRDdXJyZW50VVJMXG4gICAgICAgICAgICAgICAgJiYgdGhpcy5yZWh5ZHJhdGVkQ3VycmVudFVSTC5nZXRQYXRoKCkgPT09IHVybC5nZXRQYXRoKCkpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb25Db250ZXh0LnJlaHlkcmF0ZWRNb2RlbCA9IHRoaXMucmVoeWRyYXRlZE1vZGVsO1xuICAgICAgICAgICAgICAgIHRoaXMucmVoeWRyYXRlZEN1cnJlbnRVUkwgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMucmVoeWRyYXRlZE1vZGVsID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFjdGlvbkNvbnRleHQuZXJDb250ZXh0ID0gdGhpcy5nZXRFckNvbnRleHQoKTtcblxuICAgICAgICAgICAgZXZlbnRCdXMgJiYgZXZlbnRCdXMuZmlyZSgnZm9yd2FyZGFjdGlvbicsIHV0aWwubWl4KHtjb250cm9sbGVyOiB0aGlzfSwgYWN0aW9uQ29udGV4dCkpO1xuICAgICAgICAgICAgY29uc3QgbG9hZGVyID0gdGhpcy5sb2FkQWN0aW9uKGFjdGlvbkNvbnRleHQpO1xuICAgICAgICAgICAgYXNzZXJ0Lmhhcyhsb2FkZXIsICdsb2FkQWN0aW9uIHNob3VsZCBhbHdheXMgcmV0dXJuIGEgUHJvbWlzZScpO1xuXG4gICAgICAgICAgICByZXR1cm4gbG9hZGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVuZGVyQWN0aW9uKHVybCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB1cmwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdXJsID0gVVJMLnBhcnNlKHVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5nbG9iYWxBY3Rpb25Mb2FkZXIgJiYgdHlwZW9mIHRoaXMuZ2xvYmFsQWN0aW9uTG9hZGVyLmFib3J0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nbG9iYWxBY3Rpb25Mb2FkZXIuYWJvcnQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudEFjdGlvblxuICAgICAgICAgICAgICAgICYmIHR5cGVvZiB0aGlzLmN1cnJlbnRBY3Rpb24uZmlsdGVyUmVkaXJlY3QgPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAmJiB0aGlzLmN1cnJlbnRBY3Rpb24uZmlsdGVyUmVkaXJlY3QodXJsKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ1JlZGlyZWN0IGFib3J0ZWQgYnkgcHJldmlvdXMgYWN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuZ2xvYmFsQWN0aW9uTG9hZGVyID0gdGhpcy5mb3J3YXJkKHVybCwgdGhpcy5nZXRNYWluQ29udGFpbmVyKCksIG51bGwsIGZhbHNlKTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50QnVzID0gdGhpcy5nZXRFdmVudEJ1cygpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nbG9iYWxBY3Rpb25Mb2FkZXJcbiAgICAgICAgICAgICAgICAudGhlbihhcmdzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW50ZXJBY3Rpb24uY2FsbCh0aGlzLCBhcmdzLmFjdGlvbiwgYXJncy5hY3Rpb25Db250ZXh0KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC50aGVuKG51bGwsIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBldmVudEJ1cyAmJiBldmVudEJ1cy5ub3RpZnlFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgZW50ZXJDaGlsZEFjdGlvbihhY3Rpb24sIGFjdGlvbkNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuY2hpbGRBY3Rpb25Mb2FkZXJzW2FjdGlvbkNvbnRleHQuY29udGFpbmVyXSA9IG51bGw7XG5cbiAgICAgICAgICAgIGxldCBjb250YWluZXI7XG4gICAgICAgICAgICBpZiAoZ2xvYmFsLmRvY3VtZW50ICYmIGdsb2JhbC5kb2N1bWVudC5nZXRFbGVtZW50QnlJZCkge1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lciA9IGdsb2JhbC5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChhY3Rpb25Db250ZXh0LmNvbnRhaW5lcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbG9jYXRvciA9IHRoaXMuZ2V0TG9jYXRvcigpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRyb2xsZXIgPSB0aGlzO1xuXG4gICAgICAgICAgICBjb25zdCByZWRpcmVjdCA9ICh1cmwsIG9wdGlvbnMsIGV4dHJhKSA9PiB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgICAgICAgICAgICAgdXJsID0gbG9jYXRvci5yZXNvbHZlVVJMKHVybCwgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5nbG9iYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2xvYmFsUmVkaXJlY3RQZXJmb3JtZWQgPSBsb2NhdG9yLnJlZGlyZWN0KHVybCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChnbG9iYWxSZWRpcmVjdFBlcmZvcm1lZCAmJiBjb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNoaWxkQWN0aW9uKGN1cnJlbnRDb250cm9sbGVyLCBjb250YWluZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBnbG9iYWxSZWRpcmVjdFBlcmZvcm1lZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZEFjdGlvbkluZm8gPSBjdXJyZW50Q29udHJvbGxlci5jaGlsZEFjdGlvbk1hcHBpbmdbYWN0aW9uQ29udGV4dC5jb250YWluZXJdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5nZWQgPSB1cmwudG9TdHJpbmcoKSAhPT0gY2hpbGRBY3Rpb25JbmZvLnVybC50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZFBlcmZvcm1SZWRpcmVjdCA9IGNoYW5nZWQgfHwgb3B0aW9ucy5mb3JjZTtcbiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUGVyZm9ybVJlZGlyZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRBY3Rpb25JbmZvLnVybCA9IHVybDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDb250cm9sbGVyLnJlbmRlckNoaWxkQWN0aW9uKHVybCwgY2hpbGRBY3Rpb25JbmZvLmNvbnRhaW5lciwgZXh0cmEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNob3VsZFBlcmZvcm1SZWRpcmVjdDtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGlzQ2hpbGRBY3Rpb25SZWRpcmVjdGVkID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICAvLyDpmaTkvY7niYjmnKxJReWklu+8jOWFtuWug+a1j+iniOWZqOaYr+WPr+S7peWcqOS6i+S7tuWvueixoeS4iuWKoOiHquWumuS5ieWxnuaAp+eahO+8jElF5q+P5qyh6YO955Sf5oiQ5paw55qE5LqL5Lu25a+56LGh5omA5Lul5L+d55WZ5LiN5LqG6L+Z5Lqb5bGe5oCn77yMXG4gICAgICAgICAgICAgICAgLy8g5Zyo6L+Z6YeM5LyY5YWI55So6Ieq5a6a5LmJ5bGe5oCn5o6n5Yi277yM6YG/5YWN5a+5RE9N5qCR5peg5oSP5LmJ55qE6YGN5Y6G77yM5Y+q5pyJ5Zyo5rKh5pyJ5bGe5oCn55qE5pe25YCZ77yM5omN5ZCR5ZCO5YW85a656IezRE9N5qCR55qE6YGN5Y6GXG4gICAgICAgICAgICAgICAgaWYgKGUuaXNDaGlsZEFjdGlvblJlZGlyZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IGlubmVybW9zdENvbnRhaW5lciA9IGUudGFyZ2V0IHx8IGUuc3JjRWxlbWVudDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoaW5uZXJtb3N0Q29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIOaYr0FjdGlvbuWuueWZqOeahOWFg+e0oOiCr+WumuespuWQiOS7peS4i+adoeS7tu+8mlxuICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgICAgICAvLyAtIOacieS4qmBpZGDvvIzlm6DkuLrmsqHmnIlgaWRg5LiN6IO95riy5p+T5a2QQWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIC8vIC0g6L+Z5LiqYGlkYOWcqGBjaGlsZEFjdGlvbk1hcHBpbmdg6YeM5piv5pyJ5a+55bqU55qE5YC855qEXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbm5lcm1vc3RDb250YWluZXIuaWQgJiYgY3VycmVudENvbnRyb2xsZXIuY2hpbGRBY3Rpb25NYXBwaW5nW2lubmVybW9zdENvbnRhaW5lci5pZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaW5uZXJtb3N0Q29udGFpbmVyID0gaW5uZXJtb3N0Q29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIOWmguaenOacgOaOpei/keiiq+eCueWHu+eahOmTvuaOpeeahEFjdGlvbuWuueWZqOaYr+S4jeaYr+W9k+WJjeeahOi/meS4quWuueWZqO+8jOWwseivtOaYjuWcqOW9k+WJjeWuueWZqOWSjOmTvuaOpeS5i+mXtOi/mOacieS4gOWxguS7peS4iueahOWtkEFjdGlvbu+8jFxuICAgICAgICAgICAgICAgIC8vIOmCo+S5iOi/meS4quWtkEFjdGlvbuiCr+WumuS8muWkhOeQhuaOiei/meS4qumTvuaOpeeahOi3s+i9rO+8jOS4jemcgOimgei/memHjOWkhOeQhuS6hlxuICAgICAgICAgICAgICAgIGlmIChpbm5lcm1vc3RDb250YWluZXIuaWQgIT09IGFjdGlvbkNvbnRleHQuY29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGUuaXNDaGlsZEFjdGlvblJlZGlyZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyDpnIDopoHmiopgY29udGFpbmVyYOS4iueahOmTvuaOpeeCueWHu+WFqOmDqOaLpuaIquS4i+adpe+8jOWmguaenOaYr2hhc2jot7PovazvvIzliJnovazliLBjb250cm9sbGVy5LiK5p2lXG4gICAgICAgICAgICBjb25zdCBoaWphY2sgPSAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIOS4i+mdouS4pOihjOaYr+S7peS4u+a1gea1j+iniOWZqOS4uuS4u++8jOWFvOWuuUlF55qE5LqL5Lu25bGe5oCn5pON5L2cXG4gICAgICAgICAgICAgICAgZSA9IGUgfHwgKGdsb2JhbC53aW5kb3cgJiYgZ2xvYmFsLndpbmRvdy5ldmVudCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50O1xuXG4gICAgICAgICAgICAgICAgLy8g5ouF5b+D5pyJ5Lq65ZyoYDxzcGFuPmDkuYvnsbvnmoTkuIrpnaLmlL5gaHJlZmDlsZ7mgKfvvIzov5jmmK/liKTmlq3kuIDkuIvmoIfnrb5cbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09ICdhJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gYDxhPmDlhYPntKDkuZ/lj6/og73msqHmnIlgaHJlZmDlsZ7mgKdcbiAgICAgICAgICAgICAgICBjb25zdCBocmVmID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnaHJlZicsIDIpIHx8ICcnO1xuICAgICAgICAgICAgICAgIC8vIOaYr2hhc2jot7PovaznmoTpk77mjqXlsLHlj5bmtojmjonpu5jorqTnmoTot7PovazooYzkuLpcbiAgICAgICAgICAgICAgICBpZiAoaHJlZi5jaGFyQXQoMCkgIT09ICcjJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIOWmguaenOacieS4i+mdoueahOWtkEFjdGlvbuWkhOeQhuS6hui3s+i9rO+8jOmCo+i/memHjOWwseWVpeS5n+S4jeW5suS6hlxuICAgICAgICAgICAgICAgIGlmIChpc0NoaWxkQWN0aW9uUmVkaXJlY3RlZChlKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGUucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIOi9rOWIsGByZW5kZXJDaGlsZEFjdGlvbmDkuIpcbiAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBocmVmLnN1YnN0cmluZygxKTtcblxuICAgICAgICAgICAgICAgIC8vIOebtOaOpeS9v+eUqOS4k+S+m+WtkEFjdGlvbuS4iueahGByZWRpcmVjdGDmlrnms5XvvIxcbiAgICAgICAgICAgICAgICAvLyDkvJroh6rliqjlpITnkIZgaGlqYWNrYOeahOino+e7keWumuOAgVVSTOavlOWvueOAgei/m+WFpeWtkEFjdGlvbuetieS6i++8jFxuICAgICAgICAgICAgICAgIC8vIOS4uuWFjUFjdGlvbumHjeWGmWByZWRpcmVjdGDmlrnms5XvvIzov5nph4znlKjpl63ljIXlhoXnmoTov5nkuKpcbiAgICAgICAgICAgICAgICBjb25zdCByZWRpcmVjdEF0dHJpYnV0ZXMgPSAodGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1yZWRpcmVjdCcpIHx8ICcnKS5zcGxpdCgvWyxcXHNdLyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVkaXJlY3RPcHRpb25zID0ge307XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWRpcmVjdEF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVkaXJlY3RBdHRyaWJ1dGVOYW1lID0gdXRpbC50cmltKHJlZGlyZWN0QXR0cmlidXRlc1tpXSk7XG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0T3B0aW9uc1tyZWRpcmVjdEF0dHJpYnV0ZU5hbWVdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVkaXJlY3QodXJsLCByZWRpcmVjdE9wdGlvbnMpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgYWN0aW9uLnJlZGlyZWN0ID0gcmVkaXJlY3Q7XG5cbiAgICAgICAgICAgIGFjdGlvbi5yZWxvYWQgPSBmdW5jdGlvbiAoZXh0cmEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlZGlyZWN0KGFjdGlvbkNvbnRleHQudXJsLCB7Zm9yY2U6IHRydWV9LCBleHRyYSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBhY3Rpb24uYmFjayA9IGZ1bmN0aW9uIChkZWZhdWx0VVJMLCBleHRyYSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZmVycmVyID0gdGhpcy5jb250ZXh0ICYmIHRoaXMuY29udGV4dC5yZWZlcnJlcjtcbiAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSByZWZlcnJlciB8fCBkZWZhdWx0VVJMO1xuICAgICAgICAgICAgICAgIHRoaXMucmVkaXJlY3QodXJsLCBudWxsLCBleHRyYSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYWRkQ2hpbGRBY3Rpb24odGhpcywgY29udGFpbmVyLCBhY3Rpb24sIGhpamFjaywgYWN0aW9uQ29udGV4dCk7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVudGVyQWN0aW9uKGFjdGlvbiwgYWN0aW9uQ29udGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICByZW5kZXJDaGlsZEFjdGlvbih1cmwsIGNvbnRhaW5lciwgb3B0aW9ucykge1xuICAgICAgICAgICAgYXNzZXJ0Lmhhcyhjb250YWluZXIpO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB1cmwgPSBVUkwucGFyc2UodXJsKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNMb2FkZXIgPSB0aGlzLmNoaWxkQWN0aW9uTG9hZGVyc1tjb250YWluZXJdO1xuICAgICAgICAgICAgaWYgKHByZXZpb3VzTG9hZGVyICYmIHR5cGVvZiBwcmV2aW91c0xvYWRlci5hYm9ydCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHByZXZpb3VzTG9hZGVyLmFib3J0KCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbkluZm8gPSB0aGlzLmNoaWxkQWN0aW9uTWFwcGluZ1tjb250YWluZXJdO1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNBY3Rpb24gPSBhY3Rpb25JbmZvICYmIGFjdGlvbkluZm8uYWN0aW9uO1xuICAgICAgICAgICAgaWYgKHByZXZpb3VzQWN0aW9uXG4gICAgICAgICAgICAgICAgJiYgdHlwZW9mIHByZXZpb3VzQWN0aW9uLmZpbHRlclJlZGlyZWN0ID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgJiYgcHJldmlvdXNBY3Rpb24uZmlsdGVyUmVkaXJlY3QodXJsKSA9PT0gZmFsc2VcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnUmVkaXJlY3QgYWJvcnRlZCBieSBwcmV2aW91cyBhY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbG9hZGVyID0gdGhpcy5mb3J3YXJkKHVybCwgY29udGFpbmVyLCBvcHRpb25zLCB0cnVlKTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHRoaXMuZ2V0RXZlbnRCdXMoKTtcbiAgICAgICAgICAgIGNvbnN0IGxvYWRpbmdDaGlsZEFjdGlvbiA9IGxvYWRlclxuICAgICAgICAgICAgICAgIC50aGVuKGFyZ3MgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbnRlckNoaWxkQWN0aW9uLmNhbGwodGhpcywgYXJncy5hY3Rpb24sIGFyZ3MuYWN0aW9uQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAudGhlbihudWxsLCB1dGlsLmJpbmQoZXZlbnRzLm5vdGlmeUVycm9yLCBldmVudHMpKTtcbiAgICAgICAgICAgIC8vIGB0aGVuYOaWueazleS8mui/lOWbnuS4gOS4quaWsOeahGBQcm9taXNlYO+8jOS9huWOn+adpeeahGBsb2FkZXJg5LiK5pyJ5LiqYGFib3J0YOaWueazle+8jOimgeaKiui/meS4quaWueazleeVmeS4i+adpVxuICAgICAgICAgICAgbG9hZGluZ0NoaWxkQWN0aW9uLmFib3J0ID0gbG9hZGVyLmFib3J0O1xuICAgICAgICAgICAgdGhpcy5jaGlsZEFjdGlvbkxvYWRlcnNbY29udGFpbmVyXSA9IGxvYWRpbmdDaGlsZEFjdGlvbjtcbiAgICAgICAgICAgIHJldHVybiBsb2FkaW5nQ2hpbGRBY3Rpb247XG4gICAgICAgIH1cblxuICAgICAgICByZWh5ZHJhdGUocmVoeWRyYXRlZFN0YXRlKSB7XG4gICAgICAgICAgICBpZiAocmVoeWRyYXRlZFN0YXRlICYmIHJlaHlkcmF0ZWRTdGF0ZS5jdXJyZW50VVJMKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWh5ZHJhdGVkQ3VycmVudFVSTCA9IFVSTC5wYXJzZShyZWh5ZHJhdGVkU3RhdGUuY3VycmVudFVSTCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWh5ZHJhdGVkTW9kZWwgPSB1dGlsLm1peCh7fSwgcmVoeWRyYXRlZFN0YXRlLm1vZGVsLCB7dXJsOiB0aGlzLnJlaHlkcmF0ZWRDdXJyZW50VVJMfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0aWMgZ2V0UmVxdWlyZSAoKSB7XG4gICAgICAgICAgICByZXR1cm4gQ29udHJvbGxlci5yZXF1aXJlIHx8IHJlcXVpcmU7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0aWMgc2V0UmVxdWlyZSAocmVxdWlyZSkge1xuICAgICAgICAgICAgQ29udHJvbGxlci5yZXF1aXJlID0gcmVxdWlyZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCBpbnN0YW5jZSA9IG5ldyBDb250cm9sbGVyKCk7XG4gICAgaW5zdGFuY2UuQ29udHJvbGxlciA9IENvbnRyb2xsZXI7XG5cbiAgICByZXR1cm4gaW5zdGFuY2U7XG59KTtcbiJdfQ==